package com.whu801.controller;

import com.alibaba.fastjson.JSON;
import com.whu801.storage.StorageException;
import com.whu801.storage.StorageFileNotFoundException;
import com.whu801.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/fs")
public class FileUploadController {

    private final StorageService storageService;

    private static final List<String> bottleTypes =Arrays.asList("PLUS100","东方树叶乌龙茶","东鹏特饮","优益C","佳得乐",
            "农夫山泉", "农夫果园","冰锐-粉","冰锐-紫","加多宝听装","加多宝瓶装","可口可乐mini","可口可乐听装",
            "可口可乐瓶装","可口可乐零度","哇哈哈AD钙奶","安慕希牛奶","小明同学-黄","尖叫","康师傅冰红茶",
            "怡宝","恒大冰泉","昆仑山","海之言","爱夸","特仑苏牛奶","王老吉听装","王老吉瓶装",
            "百事可乐听装","百事可乐瓶装","百岁山","红牛","统一冰红茶","维他柠檬茶","美年达","脉动",
            "芬达听装","茶n","莫斯利安牛奶","蓝带啤酒","金典牛奶","雀巢咖啡","雪碧mini","雪碧听装",
            "雪碧瓶装","雪花啤酒","青岛啤酒大听装","青岛啤酒小听装");

    @Autowired
    public FileUploadController(StorageService storageService) {
        this.storageService = storageService;
    }

    @GetMapping("/bottle/classes")
    @ResponseBody
    public String getAvailableBottleClasses() {
        HashMap<String, Object> res = new HashMap<String, Object>();
        res.put("code", 1);
        res.put("classes", bottleTypes);
        return JSON.toJSONString(res);
    }

    @GetMapping("/")
    public String listUploadedFiles(Model model) throws IOException {

        model.addAttribute("files", storageService.loadAllBottles().map(
                path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class,
                        "serveBottleFile", path.getFileName().toString()).build().toString())
                .collect(Collectors.toList()));
        model.addAttribute("bottleTypes", bottleTypes);

        return "uploadForm";
    }

    @GetMapping("/files/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> serveFile(@PathVariable String filename) {

        Resource file = storageService.loadAsResource(filename);
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + file.getFilename() + "\"").body(file);
    }

    @GetMapping("/bottles/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> serveBottleFile(@PathVariable String filename) {

        Resource file = storageService.loadBottleAsResource(filename);
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_TYPE,
                "image/png").body(file);
    }

    @PostMapping("/")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {

        storageService.store(file);
        redirectAttributes.addFlashAttribute("message",
                "You successfully uploaded " + file.getOriginalFilename() + "!");

        return "redirect:/";
    }

    @PostMapping("/uploadBottle")
    @ResponseBody
    public String uploadBottle(@RequestParam("file") MultipartFile file,
                               @RequestParam("class") String type,
                               @RequestParam("username") String username) {
        Calendar now = Calendar.getInstance();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')).toLowerCase();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = type + "_" + username + "_" + sdf.format(now.getTime()) + suffix;
        Map<String, Object> result = new HashMap<>();
        try {
            storageService.storeBottle(file, fileName);
            result.put("code", 1);
            result.put("message", "upload successfully");
        } catch (StorageException se) {
            result.put("code", 0);
            result.put("message", "upload failure");
        }
        return JSON.toJSONString(result);
    }

    @ExceptionHandler(StorageFileNotFoundException.class)
    public ResponseEntity<?> handleStorageFileNotFound(StorageFileNotFoundException exc) {
        return ResponseEntity.notFound().build();
    }

}
